package com.js.rtu;

import android.annotation.SuppressLint;
import android.app.Application;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import com.js.rtu.config.ErrConfig;
import com.js.rtu.event.onConnectionStateChangedEvent;
import com.js.rtu.fragment.forth.bd.BDBean;
import com.js.rtu.fragment.forth.bd.WriteResultBean;
import com.js.rtu.fragment.third.DebugWriteBean;
import com.js.rtu.greendao.DBHelper;
import com.js.rtu.greendao.MySQLiteOpenHelper;
import com.js.rtu.greendao.dao.DaoMaster;
import com.js.rtu.util.BleUtils;
import com.js.rtu.util.BluetoothUtils;
import com.js.rtu.util.CRC16Util;
import com.js.rtu.util.ConfigMgr;
import com.js.rtu.util.MyLog;
import com.js.rtu.util.RxTimerUtil;
import com.js.rtu.util.ToastUtil;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.DefaultRefreshFooterCreator;
import com.scwang.smartrefresh.layout.api.DefaultRefreshHeaderCreator;
import com.scwang.smartrefresh.layout.api.RefreshFooter;
import com.scwang.smartrefresh.layout.api.RefreshHeader;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.constant.SpinnerStyle;
import com.scwang.smartrefresh.layout.footer.ClassicsFooter;
import com.scwang.smartrefresh.layout.header.ClassicsHeader;
import com.tencent.bugly.Bugly;

import org.greenrobot.eventbus.EventBus;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.TimeUnit;

import cn.wandersnail.bluetooth.BTManager;
import cn.wandersnail.bluetooth.Connection;
import cn.wandersnail.bluetooth.EventObserver;
import es.dmoral.toasty.Toasty;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;


public class RTUApplication extends Application {
    private static RTUApplication app;
    MyEventObserver mMyEventObserver;
    RxTimerUtil rxTimerUtil;
    public static long lastHeartbeatTime = 0;

    @Override
    public void onCreate() {
        super.onCreate();
        Bugly.init(getApplicationContext(), "6e27138bc8", true);
        context = this;
        app = this;
        ConfigMgr.getInstance(context);
        initDb();
        mMyEventObserver = new MyEventObserver();
        BTManager.getInstance().initialize(this);
        SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() {
            @NonNull
            @Override
            public RefreshHeader createRefreshHeader(@NonNull Context context, @NonNull RefreshLayout layout) {
                layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);//全局设置主题颜色
                return new ClassicsHeader(context).setSpinnerStyle(SpinnerStyle.Translate);//指定为经典Header，默认是 贝塞尔雷达Header
            }
        });
        SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() {
            @NonNull
            @Override
            public RefreshFooter createRefreshFooter(@NonNull Context context, @NonNull RefreshLayout layout) {
                return new ClassicsFooter(context).setSpinnerStyle(SpinnerStyle.Translate);
            }
        });


    }

    public static RTUApplication getInstance() {
        return app;
    }


    private static Context context;


    public static Context getAppContext() {
        return context;
    }


    public Connection connection;
    public BluetoothDevice device;
    StringBuilder stringBuilder = new StringBuilder();

    public Connection getConnection(String mac) {
        return connection = BTManager.getInstance().createConnection(mac, mMyEventObserver);
    }

    public Connection getConnection(BluetoothDevice device) {
        return connection = BTManager.getInstance().createConnection(device, mMyEventObserver);

    }


//    public void startReveiveData() {
//
//        rxTimerUtil = new RxTimerUtil();
//        rxTimerUtil.interval(1000, new RxTimerUtil.IRxNext() {
//            @Override
//            public void doNext(long number) {
//                if (dataList.size() == 0) {
//                    return;
//                }
//                int num = 0;//计数
//                int length = 0;//数据长度，不含头尾
//                boolean receiveEE_1 = false;//EE
//                boolean receiveEE_2 = false;//EE
//                boolean receiveAddress = false;//地址位 长度8
//                boolean receiveLength = false;//帧长 长度2 字节
//                boolean receiveData = false;//数据
//                boolean receiveFF_1 = false;//FF
//                boolean receiveFF_2 = false;//FF
//                ListIterator<String> hexStr = dataList.listIterator();
//                while (hexStr.hasNext()) {
//                    String msg = hexStr.next();
//                    index.add(msg);
//                    hexStr.remove();
//                    if (receiveFF_1
////                            && msg.equals("FF")
//                    ) {
//                        //收到第二个FF，符合帧尾,回调数据，结束本次循环
////                        Log.e("onRead", "收到第二个FF，符合帧尾");
//                        checkData(index);
//                        index.clear();
//                        break;
//                    }
//
//                    if (receiveData
////                            && !receiveFF_1 && msg.equals("FF")
//                    ) {
//                        //收到第一个FF
//                        receiveFF_1 = true;
////                        Log.e("onRead", "收到第一个FF");
//                    }
//
//                    if (receiveEE_2 && !receiveData) {
//                        //帧头后的数据
//                        num++;
////                        Log.e("onRead", "帧头后的数据" + num);
//                    }
//                    if (length == index.size()) {
//                        //数据段接收完毕
//                        receiveData = true;
////                        Log.e("onRead", "数据段接收完毕");
//                    }
//
//                    if (length == 0 && receiveLength) {
//                        //解析数据长度
//                        length = BleUtils.hToint(index.get(11) + index.get(10)) + 2;
////                        Log.e("onRead", "length"+length);
////
//                    }
//                    if (receiveAddress && num == 10) {
//                        //收到9-10，为数据长度字段2字节
//                        receiveLength = true;
////                        Log.e("onRead", "收到9-10，为数据长度字段2字节");
//                    }
//                    if (num == 8) {
//                        //收到8个地址位
//                        receiveAddress = true;
////                        Log.e("onRead", "收到8个地址位");
//                    }
//
//                    if (receiveEE_1 && msg.equals("EE")) {
//                        //收到第二个EE，符合帧头
//                        receiveEE_2 = true;
////                        Log.e("onRead", "收到第二个EE，符合帧头");
//                    }
//                    if (!receiveEE_1 && msg.equals("EE")) {
//                        //收到第一个EE
//                        receiveEE_1 = true;
////                        Log.e("onRead", "收到第一个EE");
//                    }
//                    if (!receiveEE_1) {
////                        index.clear();
//                    }
//                }
//
//            }
//        });
//    }


    public void checkData(StringBuilder stringBuilder) {
        Log.e("onRead", stringBuilder.toString());
        MyLog.writeLogtoFile("接收成功:\n" + stringBuilder.toString());


        String dataStr = stringBuilder.toString();
        BDBean bdBean = new BDBean();
        if (CRC16Util.iscrc(dataStr)) {
            String[] data = dataStr.split(" ");
            if (data[12].equals("FE")) {
                if (mCallback != null) {
                    mCallback.onFail("指令" + data[13] + "错误，" +
                            ErrConfig.getErr(Integer.parseInt(data[14])));
                }
                bdBean.setSuccess(false);
                if (mCallback != null) {
                    mCallback.onReceive(dataStr);
                }
            } else {
                if (mCallback != null) {
                    mCallback.onReceive(dataStr);
                }
                bdBean.setSuccess(true);
            }
            bdBean.setData(dataStr);
            EventBus.getDefault().post(bdBean);

        } else {
            if (mCallback != null) {
                mCallback.onFail("crc校验失败");
            }
            ToastUtil.error("crc校验失败");
        }
    }


    public class MyEventObserver implements EventObserver {
        private MyEventObserver() {

        }

        @Override
        public void onBluetoothAdapterStateChanged(int state) {

        }

        @Override
        public void onRead(@NonNull BluetoothDevice device, @NonNull byte[] value) {
            if (value.length == 0) {
                return;
            }
            for (byte pB : value) {
                String msg = int2hexString(pB);
                if (msg != null && !msg.isEmpty()) {
                    stringBuilder.append(msg);
                    stringBuilder.append(' ');
                }

            }
//            Log.e("onRead", stringBuilder.toString());

//            //帧头EE EE
            if (!stringBuilder.toString().startsWith("EE EE")) {
                stringBuilder.delete(0, stringBuilder.length());
                Log.e("onRead", "帧头EE EE不符合:" + stringBuilder.toString());
                return;
            }
            //长度
            if (stringBuilder.length() >= 34) {
                //11 12字节为帧数据长度，低字节在前
                String leng_1 = stringBuilder.charAt(30) + "" + stringBuilder.charAt(31);
                String leng_2 = stringBuilder.charAt(33) + "" + stringBuilder.charAt(34);
                int length = BleUtils.hToint(leng_2 + leng_1) + 4;
                if (stringBuilder.length() < length * 3) {
                    return;
                }
            }

            //帧尾FF FF
            if (!stringBuilder.toString().endsWith("FF FF ")) {
                Log.e("onRead", "帧尾不符合:" + stringBuilder.toString());
                stringBuilder.delete(0, stringBuilder.length());
                return;
            }
            checkData(stringBuilder);
            stringBuilder.delete(0, stringBuilder.length());
            mCallback = null;

        }

        @SuppressLint("CheckResult")
        @Override
        public void onWrite(@NonNull BluetoothDevice device, @NonNull String tag, @NonNull byte[] value,
                            final boolean result) {

            Observable
                    .timer(500, TimeUnit.MILLISECONDS)
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnComplete(new Action() {
                        @Override
                        public void run() throws Exception {
                            String msg = "发送失败:";
                            if (result) {
                                msg = "发送成功:";
                            }
                            EventBus.getDefault().post(new DebugWriteBean(msg + tag));
                            EventBus.getDefault().post(new WriteResultBean(result, tag));
                            String[] cmd = tag.split(" ");
                            if (cmd.length >= 12 && cmd[12].equals("21")) {
                                return;
                            }
//                            ToastUtil.success( result ? "发送成功" : "发送失败");
                        }
                    })
                    .subscribe();
        }


        @Override
        public void onConnectionStateChanged(@NonNull BluetoothDevice device, int state) {
            EventBus.getDefault().post(new onConnectionStateChangedEvent(device, state));
            switch (state) {
                case Connection.STATE_CONNECTING:
//                    EventBus.getDefault().post("正在连接");
                    break;
                case Connection.STATE_PAIRING:
//                    EventBus.getDefault().post("配对中");
                    break;
                case Connection.STATE_PAIRED:
//                    EventBus.getDefault().post("已配对");
                    break;
                case Connection.STATE_CONNECTED:
                    EventBus.getDefault().post("已连接");
                    ToastUtil.success("已连接");
                    break;
                case Connection.STATE_DISCONNECTED:
                    EventBus.getDefault().post("连接已断开");
                    rxTimerUtil.cancel();
                    ToastUtil.error("连接已断开");
                    break;
                case Connection.STATE_RELEASED:
                    EventBus.getDefault().post("连接已释放");
                    rxTimerUtil.cancel();
                    ToastUtil.error("连接已释放");
                    break;
                default:
                    break;
            }
        }
    }


    public void releaseConnection() {
        if (connection != null && !connection.isReleased()) {
            connection.release();
        }
        device = null;

    }

    public void write(String message, BluetoothUtils.onCallback pCallBack) {
        if (connection == null || !connection.isConnected()) {
            pCallBack.onFail("请链接设备");
//            EventBus.getDefault().post("请链接设备");
            return;
        }
        mCallback = pCallBack;
        RTUApplication.lastHeartbeatTime = new Date(System.currentTimeMillis()).getTime();
        new Thread(new Runnable() {
            @Override
            public void run() {
                String[] data = message.split(" ");
                byte[] tmp = new byte[data.length];
                for (int i = 0; i < data.length; i++) {
                    tmp[i] = (byte) Integer.parseInt(data[i], 16);
                }
                try {
                    Thread.sleep(100);

//                    connection.clearQueue();

                    connection.write(message, tmp, null);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }).start();

    }


    /**
     * 10进制转16,自动补0
     * 1个byte型的单字节十六进制
     *
     * @param number
     * @return
     */
    private static String int2hexString(int number) {
        return Integer.toHexString((number & 0x000000ff) | 0xffffff00)
                .substring(6).toUpperCase();
    }

    BluetoothUtils.onCallback mCallback;

    /**
     * 初始化数据库
     */
    private void initDb() {

        DBHelper.getInstance().init(getApplicationContext());

        MySQLiteOpenHelper helper = new MySQLiteOpenHelper(this, "testDb.db",
                null);
        new DaoMaster(helper.getWritableDatabase());
    }

}